// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraGameplayAbility_Jump.h"

#include "AbilitySystem/Abilities/LyraGameplayAbility.h"
#include "Character/LyraCharacter.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraGameplayAbility_Jump)

struct FGameplayTagContainer;

/**
 * 构造函数，初始化跳跃能力。
 * @param ObjectInitializer 对象初始化器
 */
ULyraGameplayAbility_Jump::ULyraGameplayAbility_Jump(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer) // 调用父类构造函数
{
	InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor; // 设置实例化策略为每个执行者实例化
	NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted; // 设置网络执行策略为本地预测
}

/**
 * 检查跳跃能力是否可以被激活。
 * @param Handle 能力规格句柄
 * @param ActorInfo 能力执行者信息
 * @param SourceTags 源标签容器
 * @param TargetTags 目标标签容器
 * @param OptionalRelevantTags 可选相关标签容器
 * @return 如果能力可以激活则返回true，否则返回false
 */
bool ULyraGameplayAbility_Jump::CanActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayTagContainer* SourceTags, const FGameplayTagContainer* TargetTags, FGameplayTagContainer* OptionalRelevantTags) const
{
	if (!ActorInfo || !ActorInfo->AvatarActor.IsValid()) // 检查执行者信息或AvatarActor是否有效
	{
		return false; // 如果无效则返回false
	}

	const ALyraCharacter* LyraCharacter = Cast<ALyraCharacter>(ActorInfo->AvatarActor.Get()); // 将AvatarActor转换为LyraCharacter
	if (!LyraCharacter || !LyraCharacter->CanJump()) // 检查LyraCharacter是否有效且可以跳跃
	{
		return false; // 如果无效或不能跳跃则返回false
	}

	if (!Super::CanActivateAbility(Handle, ActorInfo, SourceTags, TargetTags, OptionalRelevantTags)) // 调用父类的CanActivateAbility方法
	{
		return false; // 如果父类检查失败则返回false
	}

	return true; // 所有检查通过，返回true
}

/**
 * 结束跳跃能力时调用。
 * @param Handle 能力规格句柄
 * @param ActorInfo 能力执行者信息
 * @param ActivationInfo 能力激活信息
 * @param bReplicateEndAbility 是否复制结束能力
 * @param bWasCancelled 能力是否被取消
 */
void ULyraGameplayAbility_Jump::EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled)
{
	// 停止跳跃，以防能力蓝图没有调用它。
	CharacterJumpStop(); // 调用CharacterJumpStop方法

	Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled); // 调用父类的EndAbility方法
}

/**
 * 开始角色跳跃。
 */
void ULyraGameplayAbility_Jump::CharacterJumpStart()
{
	if (ALyraCharacter* LyraCharacter = GetLyraCharacterFromActorInfo()) // 从ActorInfo获取LyraCharacter
	{
		if (LyraCharacter->IsLocallyControlled() && !LyraCharacter->bPressedJump) // 检查角色是否本地控制且未按下跳跃键
		{
			LyraCharacter->UnCrouch(); // 取消蹲下状态
			LyraCharacter->Jump(); // 执行跳跃
		}
	}
}

/**
 * 停止角色跳跃。
 */
void ULyraGameplayAbility_Jump::CharacterJumpStop()
{
	if (ALyraCharacter* LyraCharacter = GetLyraCharacterFromActorInfo()) // 从ActorInfo获取LyraCharacter
	{
		if (LyraCharacter->IsLocallyControlled() && LyraCharacter->bPressedJump) // 检查角色是否本地控制且已按下跳跃键
		{
			LyraCharacter->StopJumping(); // 停止跳跃
		}
	}
}